package parser

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"save-kindle/log"
	"text/template"
)

type OpfEntity struct {
	Title     string
	Creator   []string
	Publisher string
	Manifest  []OpfManifest
	Ncx       []OpfNcx
}

type OpfManifest struct {
	// application/xhtml+xml
	// text/css
	// image/jpeg
	// application/x-dtbncx+xml
	MediaType string
	// 指从 OEBPS 开始的路径
	// Text
	// Styles
	// Images
	CurCount int
}

type OpfNcx struct {
	Idref string
}

type XhtmlP struct {
}

type TableContent struct {
	FileName string
	Item     []TableContentItem
}

type TableContentItem struct {
	// 章节文件存储路径
	CurCount int
	// 章节标题
	Title string
}

type DefaultEpubParser struct {
	BookName    string
	Path        string
	MetaInfPath string
	Oebps       string
	DataMap     *OpfEntity

	ParserFinish chan int
	ListSize     int
}

func NewDefaultEpubParser(bookName string) DefaultEpubParser {
	// 构建
	return DefaultEpubParser{
		BookName:    bookName,
		Path:        fmt.Sprintf("./%s/", bookName),
		MetaInfPath: fmt.Sprintf("./%s/%s/", bookName, "META-INF"),
		Oebps:       fmt.Sprintf("./%s/%s/", bookName, "OEBPS"),
		DataMap: &OpfEntity{
			Title:     bookName,
			Creator:   []string{"Exler"},
			Publisher: "Exler",
		},
		ParserFinish: make(chan int),
	}
}

func (parser DefaultEpubParser) Gen() {
	// META-INF
	parser.genMeta()
	// mimetype
	parser.genMimetype()
	// oebps
	parser.genOebps()
}

func (parser DefaultEpubParser) genMeta() {
	os.MkdirAll(parser.MetaInfPath, 0777)
	// META-INF
	templateFile, err := os.OpenFile("./template/container.xml", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer templateFile.Close()

	targetFile, err := os.OpenFile(fmt.Sprintf("%s%s", parser.MetaInfPath, "container.xml"), os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println(err.Error())
	}
	io.Copy(targetFile, templateFile)
}

func (parser DefaultEpubParser) genMimetype() {
	// mimetype
	file, err := os.OpenFile("./"+parser.BookName+"/mimetype", os.O_CREATE|os.O_RDWR, 0666)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer file.Close()
	file.Write([]byte("application/epub+zip"))
}

func (parser DefaultEpubParser) genOebps() {
	os.MkdirAll(parser.Oebps+"Text/", 0777)
	os.MkdirAll(parser.Oebps+"Styles/", 0777)

	parser.genStyles()

	//for {
	//	select {}
	//}

	//parser.genOpf()

}

// genOpf 利用模板生成content.opf文件
func (parser DefaultEpubParser) genOpf(countList []int) {
	manifests := make([]OpfManifest, 0)
	for i := range countList {
		manifests = append(manifests, OpfManifest{
			MediaType: "application/xhtml+xml",
			CurCount:  i,
		})
	}

	parser.DataMap.Manifest = manifests

	files, err := template.ParseFiles("./template/content.opf")
	if err != nil {
		log.PrintErr(err.Error())
	}

	buffer := &bytes.Buffer{}
	err = files.Execute(buffer, parser.DataMap)

	file, err := os.OpenFile(parser.Oebps+"content.opf", os.O_CREATE|os.O_WRONLY, 0777)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer file.Close()

	buffer.WriteTo(file)
}

func (parser DefaultEpubParser) genXhtml(chapter EpubChapter) {
	files, err := template.ParseFiles("./template/template.xhtml")
	if err != nil {
		log.PrintErr(err.Error())
	}

	//chapter.FileName = parser.BookName

	buffer := &bytes.Buffer{}
	err = files.Execute(buffer, chapter)

	file, err := os.OpenFile(fmt.Sprintf("%sText/text%d.xhtml", parser.Oebps, chapter.CurCount), os.O_CREATE|os.O_WRONLY, 0777)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer file.Close()

	buffer.WriteTo(file)
}

func (parser DefaultEpubParser) genStyles() {
	// Styles
	styleFile1, err := os.OpenFile("./template/style0001.css", os.O_RDONLY, 0666)
	styleFile2, err := os.OpenFile("./template/style0002.css", os.O_RDONLY, 0666)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer styleFile1.Close()
	defer styleFile2.Close()

	targetStyleFile1, err := os.OpenFile(fmt.Sprintf("%sStyles/style0001.css", parser.Oebps), os.O_CREATE|os.O_WRONLY, 0666)
	targetStyleFile2, err := os.OpenFile(fmt.Sprintf("%sStyles/style0002.css", parser.Oebps), os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		fmt.Println(err.Error())
	}
	defer targetStyleFile1.Close()

	defer targetStyleFile2.Close()

	io.Copy(targetStyleFile1, styleFile1)
	io.Copy(targetStyleFile2, styleFile2)
}

// 生成目录
func (parser DefaultEpubParser) genTableContents(content TableContent) {
	files, err := template.ParseFiles("./template/TableContents.xhtml")
	if err != nil {
		log.PrintErr(err.Error())
	}

	content.FileName = parser.BookName

	buffer := &bytes.Buffer{}
	err = files.Execute(buffer, content)

	file, err := os.OpenFile(fmt.Sprintf("%sText/TableContent.xhtml", parser.Oebps), os.O_CREATE|os.O_WRONLY, 0777)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer file.Close()

	buffer.WriteTo(file)

	// ncx
	ncxTemplateFile, err := template.ParseFiles("./template/toc.ncx")
	if err != nil {
		log.PrintErr(err.Error())
	}

	buffer = &bytes.Buffer{}
	err = ncxTemplateFile.Execute(buffer, content)

	ncxFile, err := os.OpenFile(fmt.Sprintf("%stoc.ncx", parser.Oebps), os.O_CREATE|os.O_WRONLY, 0777)
	if err != nil {
		log.PrintErr(err.Error())
	}
	defer ncxFile.Close()

	buffer.WriteTo(ncxFile)
}

func (parser DefaultEpubParser) genZipFile() {
	//d, _ := os.Create(parser.BookName + ".epub")
	//defer d.Close()
	//
	//w := zip.NewWriter(d)
	//defer w.Close()
	//
	//files := make([]string, 0)
	//files = append(files, fmt.Sprintf("./%s/mimetype", parser.BookName))
	//
	//for _, file := range files {
	//	err := compress(file, "", w)
	//	if err != nil {
	//		return err
	//	}
	//}
	//return nil

}
